evtchn kernel interface. Fix error path in bind_evtchn_to_irqhandler.
Fix backend drivers to avoid double freeing IRQs.
Signed-off-by: Keir Fraser <keir@xensource.com>
evtchns[evtchn].handler = NULL;
}
-void unbind_evtchn_from_irq(unsigned int evtchn)
-{
- printk("unbind_evtchn_from_irq called... FIXME??\n");
- while(1);
-}
-
irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
u32 l1, l2;
}
EXPORT_SYMBOL(unbind_ipi_from_irq);
-int bind_evtchn_to_irq(unsigned int evtchn)
+static int bind_evtchn_to_irq(unsigned int evtchn)
{
int irq;
return irq;
}
-EXPORT_SYMBOL(bind_evtchn_to_irq);
-void unbind_evtchn_from_irq(unsigned int irq)
+static void unbind_evtchn_from_irq(unsigned int irq)
{
evtchn_op_t op = { .cmd = EVTCHNOP_close };
int evtchn = irq_to_evtchn[irq];
spin_unlock(&irq_mapping_update_lock);
}
-EXPORT_SYMBOL(unbind_evtchn_from_irq);
int bind_evtchn_to_irqhandler(
unsigned int evtchn,
irq = bind_evtchn_to_irq(evtchn);
retval = request_irq(irq, handler, irqflags, devname, dev_id);
- if (retval != 0)
+ if (retval != 0) {
unbind_evtchn_from_irq(irq);
+ return retval;
+ }
return irq;
}
.u.bind_interdomain.remote_dom = blkif->domid,
.u.bind_interdomain.remote_port = evtchn };
+ /* Already connected through? */
+ if (blkif->irq)
+ return 0;
+
if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
return -ENOMEM;
{
blkif_t *blkif = (blkif_t *)arg;
- if (blkif->irq)
- unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+ /* Already disconnected? */
+ if (!blkif->irq)
+ return;
+
+ unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+ blkif->irq = 0;
vbd_free(&blkif->vbd);
.u.bind_interdomain.remote_dom = netif->domid,
.u.bind_interdomain.remote_port = evtchn };
+ /* Already connected through? */
+ if (netif->irq)
+ return 0;
+
netif->comms_area = alloc_vm_area(2*PAGE_SIZE);
if (netif->comms_area == NULL)
return -ENOMEM;
{
netif_t *netif = (netif_t *)arg;
- /*
- * This can't be done in netif_disconnect() because at that point
- * there may be outstanding requests in the network stack whose
- * asynchronous responses must still be notified to the remote driver.
- */
- if (netif->irq)
- unbind_evtchn_from_irqhandler(netif->irq, netif);
+ /* Already disconnected? */
+ if (!netif->irq)
+ return;
+
+ unbind_evtchn_from_irqhandler(netif->irq, netif);
+ netif->irq = 0;
unregister_netdev(netif->dev);
extern int bind_ipi_to_irq(int ipi);
extern void unbind_ipi_from_irq(int ipi);
-/*
- * Dynamically bind an event-channel port to Linux IRQ space.
- * BIND: Returns IRQ or error.
- * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
- */
-extern int bind_evtchn_to_irq(unsigned int evtchn);
-extern void unbind_evtchn_from_irq(unsigned int irq);
-
/*
* Dynamically bind an event-channel port to an IRQ-like callback handler.
* On some platforms this may not be implemented via the Linux IRQ subsystem.